
/*
 * Copyright (c) 2003, the JUNG Project and the Regents of the University of
 * California All rights reserved.
 * 
 * This software is open-source under the BSD license; see either "license.txt"
 * or http://jung.sourceforge.net/license.txt for a description.
 * 
 */
/**
 * 
 */
package vues;

import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;

import logique.administration.AjoutVille;
import logique.administration.SuppressionTroncon;
import logique.administration.SuppressionVille;
import logique.reseau.Troncon;
import logique.reseau.Ville;
import controleur.Controleur;
import edu.uci.ics.jung.graph.Edge;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.impl.AbstractSparseEdge;
import edu.uci.ics.jung.graph.impl.DirectedSparseEdge;
import edu.uci.ics.jung.graph.impl.SparseVertex;
import edu.uci.ics.jung.graph.impl.UndirectedSparseEdge;
import edu.uci.ics.jung.visualization.Layout;
import edu.uci.ics.jung.visualization.PickSupport;
import edu.uci.ics.jung.visualization.PickedState;
import edu.uci.ics.jung.visualization.SettableVertexLocationFunction;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.AbstractPopupGraphMousePlugin;

/**
 * a plugin that uses popup menus to create vertices, undirected edges,
 * and directed edges.
 * 
 * @author Tom Nelson - RABA Technologies
 *
 */
public class EditingPopupVilleGraphMouse extends AbstractPopupGraphMousePlugin {
    
    SettableVertexLocationFunction vertexLocations;
    private PanelVilleGraph panelAdminCreaVille;
    private Hashtable<SparseVertex, Ville> map;
    private Hashtable<SparseVertex, Icon> iconMap;
    Hashtable<AbstractSparseEdge, Troncon> mapEdge;
    Controleur ct;
    Ville v;
    
    public EditingPopupVilleGraphMouse(SettableVertexLocationFunction vertexLocations, Hashtable<SparseVertex, Ville> map, Hashtable<SparseVertex, Icon> iconMap, Hashtable<AbstractSparseEdge, Troncon> mapEdge, Controleur ct) {
        this.vertexLocations = vertexLocations;
        this.map = map;
        this.iconMap = iconMap;
        this.ct = ct;
        this.mapEdge = mapEdge;
    }

    protected void handlePopup(MouseEvent e) {
        final VisualizationViewer vv =
            (VisualizationViewer)e.getSource();
        final Layout layout = vv.getGraphLayout();
        final Graph graph = layout.getGraph();
        final Point2D p = e.getPoint();
        final Point2D ivp = vv.inverseViewTransform(e.getPoint());
        PickSupport pickSupport = vv.getPickSupport();
        if(pickSupport != null) {
            
            final Vertex vertex = pickSupport.getVertex(ivp.getX(), ivp.getY());
            final Edge edge = pickSupport.getEdge(ivp.getX(), ivp.getY());
            final PickedState pickedState = vv.getPickedState();
            JPopupMenu popup = new JPopupMenu();
            
            if(vertex != null) {
                Set picked = pickedState.getPickedVertices();
                if(picked.size() > 0) {
                    JMenu directedMenu = new JMenu("Create Directed Edge");
                    popup.add(directedMenu);
                    for(Iterator iterator=picked.iterator(); iterator.hasNext(); ) {
                        final Vertex other = (Vertex)iterator.next();
                        directedMenu.add(new AbstractAction("["+other+","+vertex+"]") {
                            public void actionPerformed(ActionEvent e) {
                                Edge newEdge = new DirectedSparseEdge(other, vertex);
                                graph.addEdge(newEdge);
                                vv.repaint();
                            }
                        });
                    }
                    JMenu undirectedMenu = new JMenu("Create Undirected Edge");
                    popup.add(undirectedMenu);
                    for(Iterator iterator=picked.iterator(); iterator.hasNext(); ) {
                        final Vertex other = (Vertex)iterator.next();
                        undirectedMenu.add(new AbstractAction("[" + other+","+vertex+"]") {
                            public void actionPerformed(ActionEvent e) {
                                Edge newEdge = new UndirectedSparseEdge(other, vertex);
                                graph.addEdge(newEdge);
                                vv.repaint();
                            }
                        });
                    }
                }
                popup.add(new AbstractAction("Delete Vertex") {
                    public void actionPerformed(ActionEvent e) {
                        pickedState.pick(vertex, false);
                        graph.removeVertex(vertex);
                        Ville v = map.get(vertex);
                        ct.getAdministration().ajoutModification(new SuppressionVille(map.get(vertex)));
                        try {
                			for (Troncon troncon:v.getTroncons()){
                				ct.getAdministration().ajoutModification(new SuppressionTroncon(troncon));
                			}
                		} catch (Exception e1) {
                			// TODO Auto-generated catch block
                			e1.printStackTrace();
                		}
                        vv.repaint();
                    }});
            } else if(edge != null) {
                popup.add(new AbstractAction("Delete Edge") {
                    public void actionPerformed(ActionEvent e) {
                        pickedState.pick(edge, false);
                        graph.removeEdge(edge);
                        ct.getAdministration().ajoutModification(new SuppressionTroncon(mapEdge.get(edge)));
                        vv.repaint();
                    }});
            } else {
                popup.add(new AbstractAction("Create Vertex") {
                    public void actionPerformed(ActionEvent e) {
                    	
                    	panelAdminCreaVille = new PanelVilleGraph(EditingPopupVilleGraphMouse.this, vv, graph, p);
                    	
//                    	if (v != null){
//	                        SparseVertex newVertex = new SparseVertex();
//	                        map.put(newVertex, v);
//	                        vertexLocations.setLocation(newVertex, vv.inverseTransform(p));
//	                        Layout layout = vv.getGraphLayout();
//	                        for(Iterator iterator=graph.getVertices().iterator(); iterator.hasNext(); ) {
//	                            layout.lockVertex((Vertex)iterator.next());
//	                        }
//	                        graph.addVertex(newVertex);
//	                        vv.getModel().restart();
//	                        for(Iterator iterator=graph.getVertices().iterator(); iterator.hasNext(); ) {
//	                            layout.unlockVertex((Vertex)iterator.next());
//	                        }
//	                        vv.repaint();
//	                        v = null;
//                    	}
                    }
                });
            }
            if(popup.getComponentCount() > 0) {
                popup.show(vv, e.getX(), e.getY());
            }
        }
    }
    
    protected void terminerCreationVertex(VisualizationViewer vv, Graph graph, Point2D p) {
    	if (v != null){
            SparseVertex newVertex = new SparseVertex();
            map.put(newVertex, v);
            Icon icon;
            if (v.getTaille() != null){
            	icon =  new ImageIcon(GraphEditorDemo.class.getResource("/fleches/"+v.getTaille().intitule()+".gif"));
            } else {
            	icon = new ImageIcon(GraphEditorDemo.class.getResource("/fleches/petite.gif"));
            }
            iconMap.put(newVertex, icon);
            vertexLocations.setLocation(newVertex, vv.inverseTransform(p));
            Layout layout = vv.getGraphLayout();
            for(Iterator iterator=graph.getVertices().iterator(); iterator.hasNext(); ) {
                layout.lockVertex((Vertex)iterator.next());
            }
            graph.addVertex(newVertex);
            vv.getModel().restart();
            for(Iterator iterator=graph.getVertices().iterator(); iterator.hasNext(); ) {
                layout.unlockVertex((Vertex)iterator.next());
            }
            ct.getAdministration().ajoutModification(new AjoutVille(v));
            vv.repaint();
            v = null;
    	}
    }
}
